<?php


class Core_IoUtils extends Core_Base
{
    /*
        to:
        array(
            array(
                'col1' => 'R11'
                , 'col2' => 'R12'
                , 'col3' => 'R13'
            )
            , array(
                'col1' => 'R21'
                , 'col2' => 'R22'
                , 'col3' => 'R123'
            )
        )
    */
    function formatXlsContentToData($content)
    {
        $header = current($content);
        $hindex = count($header);
        $index = count($content);
        $datas = array();
        for ($i=1; $i < $index; $i++) {
            $row = array();
            $emptyC = 0;
            for ($j = 0; $j < $hindex; $j++) {
                if (empty($content[$i][$j])) {
                    $emptyC++;
                }
                $row[$header[$j]] = $content[$i][$j];
            }
            if ($emptyC == $hindex) {
                continue;
            }
            $datas[] = $row;
        }
        return sftrim($datas);
    }
    /*
        to
        $content = array(
            array('col1', 'col2', 'col3') //表头
            , array('R11', 'R12', 'R13')  //表内容行1
            , array('R21', 'R22', 'R23')  //表内容行2
        );
    */
    function formatXlsDataToContent($data)
    {
        $header = current($data);//第一行作为列名头
        $header = array_keys($header);//已列名作为下标 处理成 array('col1' => 0, 'col2' => 1, 'col2' => 2)
        $keys = array_flip($header);//倒序列
        $keys = array_flip($keys);//换成array('col1', 'col2', 'col3')
        $klen = count($keys);
        $content = array($keys);//放入表第一行
        foreach ($result as $key => $value) {
            $row = array();
            for ($j = 0; $j < $klen; $j ++)
                $row[] = $value[$keys[$j]];
            $content[] = $row;//放入表新行
        }
        return $content;
    }

    function characetXls($data) {
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                $data[$key] = $this->characetXls($value);
            }
        } else {
            if (strlen($data) > 260) {
                $data = substr($data, 0, 260) . ' ...';
            }
            $data = iconv('UTF-8', 'gbk', $data);
        }
        return $data;
    }

    function readTable($file, $type = 'xls')
    {
        $type = strtolower($type);
        if ($type == 'csv') {
            return Core_IoUtils::instance()->getCsv($file);
        } else {
            $datas = readXls($file, $type);
            return current($datas);
        }
    }

    function readXls($file, $type = null)
    {
        if ($type == null) {
            $exts = explode('.', $file);
            $index = count($exts);
            if ($index > 1) {
                $type = end($etx);
            } else {
                $type = 'xls';
            }
        }
        $type = strtolower($type);
        switch ($type) {
            case 'xlsx':            //  Excel (OfficeOpenXML) Spreadsheet
            case 'xlsm':            //  Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
            case 'xltx':            //  Excel (OfficeOpenXML) Template
            case 'xltm':            //  Excel (OfficeOpenXML) Macro Template (macros will be discarded)
                $extensionType = 'Excel2007';
                break;
            case 'xls':             //  Excel (BIFF) Spreadsheet
            case 'xlt':             //  Excel (BIFF) Template
                $extensionType = 'Excel5';
                break;
            case 'ods':             //  Open/Libre Offic Calc
            case 'ots':             //  Open/Libre Offic Calc Template
                $extensionType = 'OOCalc';
                break;
            case 'slk':
                $extensionType = 'SYLK';
                break;
            case 'xml':             //  Excel 2003 SpreadSheetML
                $extensionType = 'Excel2003XML';
                break;
            case 'gnumeric':
                $extensionType = 'Gnumeric';
                break;
            case 'htm':
            case 'html':
                $extensionType = 'HTML';
                break;
            default:
                $extensionType = 'CSV';
                break;
        }
        sfget_instance('Class_PHPExcel');
        $reader = PHPExcel_IOFactory::createReader($extensionType);
        try {
            $PHPExcel = $reader->load($file); // 载入excel文件
        } catch (Exception $e) {
            sfpush_admin_tmp_message('读取XLS文件失败，请确保选择文件并且是：' . $extensionType . '版本！');
            sfredirect();
        }
        $sheet = $PHPExcel->getSheet(0); // 读取第一個工作表
        $highestRow = $sheet->getHighestRow(); // 取得总行数
        $highestColumm = $sheet->getHighestColumn(); // 取得总列数
        $highestColumm++;
        /** 循环读取每个单元格的数据 */
        for ($row = 1; $row <= $highestRow; $row++){//行数是以第1行开始
            $c = 0;
            for ($column = 'A'; $column != $highestColumm; $column++) {//列数是以A列开始
                $r = $row - 1;
                // $c = ord($column) - 65;
                if (!isset($dataset[$r])) {
                    $dataset[$r][$c] = array();
                }
                $dataset[$r][$c] = $sheet->getCell($column.$row)->getValue();
                if(is_object($dataset[$r][$c])){ //富文本转换字符串
                    $dataset[$r][$c] = $dataset[$r][$c]->__toString();
                }
                $c++;
            }
        }
        $datas = array($dataset); // 载入excel文件
        try{
            $sheet = $PHPExcel->getSheet(1); // 读取第一個工作表
            if ($sheet) {
                $dataset = array();
                $highestRow = $sheet->getHighestRow(); // 取得总行数
                $highestColumm = $sheet->getHighestColumn(); // 取得总列数
                $highestColumm++;
                /** 循环读取每个单元格的数据 */
                for ($row = 1; $row <= $highestRow; $row++){//行数是以第1行开始
                    $c = 0;
                    for ($column = 'A'; $column != $highestColumm; $column++) {//列数是以A列开始
                        $r = $row - 1;
                        // $c = ord($column) - 65;
                        if (!isset($dataset[$r])) {
                            $dataset[$r][$c] = array();
                        }
                        $dataset[$r][$c] = $sheet->getCell($column.$row)->getValue();
                        if(is_object($dataset[$r][$c])){ //富文本转换字符串
                            $dataset[$r][$c] = $dataset[$r][$c]->__toString();
                        }
                        $c++;
                    }
                }
                $datas[] = $dataset;
            }

        } catch (Exception $e) {}
        return $datas;
    }


    /*
        $contents = array(
            array('col1', 'col2', 'col3') //表头
            , array('R11', 'R12', 'R13')  //表内容行1
            , array('R21', 'R22', 'R23')  //表内容行2
        );
    */
    function writeXls($file, $content)
    {
        if (!function_exists('Create_Excel_File')) {
            sfget_instance('Class_Excel');
        }
        /*

        */
        $content = $this->characetXls($content);
        Create_Excel_File($file, $content);
    }


    function createDir($path, $mode = 0777)
    {
        if (!is_dir($path)) {
            mkdir($path, $mode, TRUE);
        }
    }

    function scanDir($dir_path, $level = 1, $filter = null, $isDir = false)
    {
        $returns = array();
        if (is_dir($dir_path)) {
            $handle_dir =   dir($dir_path);
            while (($file = $handle_dir->read()) !== false) {
                if (in_array($file, array('.', '..', '.svn', '.gitignore', 'Thumbs.db'))) {
                    continue;
                }
                if (!empty($filter) && !is_numeric(strpos($file, $filter))) {
                    continue;
                }
                if ($isDir && !is_dir($dir_path . DS . $file)) {
                    continue;
                }
                $returns[]  =   $file;
            }
            $handle_dir->close();
        }
        return $returns;
    }

    function readFile($file_path)
    {
        if (is_file($file_path)) {
            return file_get_contents($file_path);
        }
        return null;
    }

    function writeFile($file_path, $data, $mode = 0777)
    {
        file_put_contents($file_path,$data);
        @chmod($file_path, $mode);
    }

    function getFileTmp($path)
    {
        $tmpfname = tempnam("/tmp", "FOO");
        $handle = fopen($tmpfname, "w");
        fwrite($handle, file_get_contents($path));
        fclose($handle);
        return $tmpfname;
    }

    function deleteFile($file_path)
    {
        if (is_dir($file_path)) {
            @rmdir($file_path);
        } elseif (is_file($file_path)) {
            @unlink($file_path);
        }
    }

    function clearAllDir($dirname, $onlyFileType = null)
    {
        if (strpos($onlyFileType,'php')!= -1) {
            $onlyFileType = null;
        }
        if ($dir = @dir($dirname)) {
            $dir->rewind();
            while ($file = $dir->read()) {
                if (!in_array($file, array('.', '..', '.svn', '.gitignore', 'Thumbs.db'))) {
                    if (is_dir($dirname . '/' . $file)) {
                        sfclear_all_dir($dirname . '/' . $file, $onlyFileType);
                        !@rmdir($dirname . '/' . $file);
                    } else {
                        if ($onlyFileType !== null) {
                            $type = explode($onlyFileType, $file);
                            if (count($type) == 2 && empty($type[1])) {
                                !@unlink($dirname . '/' . $file);
                            }
                        } else {
                            !@unlink($dirname . '/' . $file);
                        }
                    }
                }
            }
            $dir->close();
        }
    }

    function getFirstFile($dir_path)
    {
        $dirs   =   Core_IoUtils::instance()->scanDir($dir_path);
        Core_IoUtils::instance()->clearInvalidDir($dirs);
        if (count($dirs)>0) {
            foreach ($dirs as $value) {
                if (!empty($value)) {
                    return $dir_path.'/'.$value;
                }
            }
        }
        return null;
    }

    function getUtf8($file_path)
    {
        if (is_file($file_path)) {
            $handle         =   fopen($file_path, 'r');
            $datas          =   '';
            while ($data = sfcharacet(fread($handle, 8192))) {
                if (!empty($data)) {
                    $datas  .=  $data."\r\n";
                }
            }
            fclose($handle);
            return $datas;
        } else {
            return null;
        }
    }

    function getCsv($file_path)
    {
        if (is_file($file_path)) {
            setlocale(LC_ALL, 'en_US.UTF-8');
            $handle =   fopen($file_path, 'r');
            while ($line = fgetcsv($handle)) {
                if (count($line) >   0) {
                    $datas[] = explode(',', sfcharacet(implode(',', $line)));
                }
            }
            fclose($handle);
            return $datas;
        } else {
            return null;
        }
    }

    function isFileMd5($file)
    {
        if (is_file($file)) {
            $name   =   basename($file);
            $names  =   explode('.', $name);
            if (md5_file($file) == current($names)) {
                return true;
            }
        }
        return false;
    }

    function getMd5Dir($name, $start = '', $level = 8)
    {
        $level--;
        $path = '';
        if (!empty($start)) {
            $fIndex = strpos($name, $start);
            if (is_numeric($fIndex)) {
                $sLen = strlen($start);
                $path = '/' . substr($name, 0, $fIndex + $sLen);
                $name = substr($name, $fIndex + $sLen);
                $level--;
            }
        }
        for ($i = 0, $index = strlen($name); $i < $index; $i++ ) {
            if ($i > $level) {
                break;
            }
            $path .= '/' . $name[$i];
        }
        return substr($path, 1);
    }

    function pushMd5File($name, $data, $base = '', $start = '', $level = 8)
    {
        $dir = Core_IoUtils::instance()->getMd5Dir($name, $start, $level);
        if (!is_dir($base . $dir)) {
            mkdir($base . $dir, 0777, true);
        }
        $file = $base . $dir . '/' . $name;
        file_put_contents($file, $data, FILE_APPEND);
        return $file;
    }

    function saveMd5File($name, $data, $base = '', $start = '', $level = 8)
    {
        $dir = Core_IoUtils::instance()->getMd5Dir($name, $start, $level);
        if (!is_dir($base . $dir)) {
            mkdir($base . $dir, 0777, true);
        }
        $file = $base . $dir . '/' . $name;
        file_put_contents($file, $data);
        return $file;
    }



    function saveMd5Copy($name, $file, $base = '', $start = '', $level = 8)
    {
        $dir = Core_IoUtils::instance()->getMd5Dir($name, $start, $level);
        if (!is_dir($base . $dir)) {
            mkdir($base . $dir, 0777, true);
        }
        $tFile = $base . $dir . '/' . $name;
        @copy($file, $tFile);
        return $file;
    }

    function saveMd5FileUpload($name, $tmp, $base = '', $start = '', $level = 8)
    {
        $dir = Core_IoUtils::instance()->getMd5Dir($name, $start, $level);
        if (!is_dir($base . $dir)) {
            mkdir($base . $dir, 0777, true);
        }
        $file = $base . $dir . '/' . $name;
        move_uploaded_file($tmp, $file);
        return $file;
    }

    function existsMd5File($name, $base = '', $start = '', $level = 8)
    {
        $file = $base . Core_IoUtils::instance()->getMd5Dir($name, $start, $level) . '/' . $name;
        if (file_exists($file)) {
            return $file;
        }
        return false;
    }

    function clearDir($dirname)
    {
        if ($dir = @dir($dirname)) {
            $dir->rewind();
            while ($file = $dir->read()) {
                if (!in_array($file, array('.', '..', '.svn', '.gitignore', 'Thumbs.db'))) {
                    if (is_dir($dirname . '/' . $file)) {
                        Core_IoUtils::instance()->clearDir($dirname . '/' . $file);
                        !@rmdir($dirname . '/' . $file);
                    } else {
                        !@unlink($dirname . '/' . $file);
                    }
                }
            }
            $dir->close();
        }
    }

    function clearInvalidDir(&$array)
    {
        if (is_array($array)) {
            foreach ($array as $key => $value) {
                switch ($value) {
                    case '.':
                    case '..':
                    case '.svn':
                    case '.gitignore':
                    case 'Thumbs.db':
                        unset($array[$key]);
                        break;
                }
            }
        }
    }
}